﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using SceneManager.Components;

namespace SceneManager
{
	public class GameObject : IDisposable
	{
		#region Variables

		private static IEnumerable<Assembly> _loadedAssemblies;
		private string _name;

		#endregion

		#region Constructors

		static GameObject()
		{
			_loadedAssemblies = Assembly.GetEntryAssembly().GetReferencedAssemblies().Select(x => Assembly.Load(x)).Concat(new[] { Assembly.GetEntryAssembly() });
		}

		public GameObject(string name)
		{
			_name = name;

			Components = new ComponentCollection(this);
		}

		public GameObject(XElement xml)
		{
			if (xml.Name != "GameObject")
			{
				throw new InvalidOperationException("Input xml does not describe a GameObject.");
			}

			_name = xml.Attribute("name").Value;

			Components = new ComponentCollection(this);
			foreach (var compXml in xml.Element("Components").Elements("Component"))
			{
				var componentName = compXml.Attribute("name").Value;
				Components.Add(FindType(componentName));
			}
		}

		#endregion

		#region Properties

		public string Name
		{
			get
			{
				return _name;
			}
			set
			{
				_name = value;
			}
		}

		public Scene Scene { get; set; }

		public ComponentCollection Components { get; private set; }

		#endregion

		#region Methods

		public void Update(GameTime gameTime)
		{
			foreach (var component in Components)
			{
				component.Update(gameTime);
			}
		}

		public void Draw(GameTime gameTime)
		{
			foreach (var component in Components)
			{
				component.Draw(gameTime);
			}
		}

		public void Dispose()
		{
			Scene = null;
		}

		private Type FindType(string typeName)
		{
			foreach (var assembly in _loadedAssemblies)
			{
				var type = assembly.GetType(typeName);
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}

		#endregion
	}
}